exports.query = function(query, resp, callback) {
    if (isNaN(query.sid) || !query.hasOwnProperty('openid') || 
        !query.hasOwnProperty('minTime') || !query.hasOwnProperty('maxTime')) {
        resp.code = 1; resp.desc = 'invalid params'; 
        callback(); return;
    }

    var sid = +query.sid;
    var openid = query.openid;

    var db = gServers.getGameDB(sid);
    if (!db) {
        resp.code = 1; resp.desc = 'invalid server'; 
        callback(); return;
    }

    db.collection('plat').findOne({_id: query.openid}, {}, function(err, result) {
        if (err || !result) {
            resp.code = 1; resp.desc = 'query uid failed';
            callback(); return;
        }

        var uid = result.uid;
        var condition = {'uid':uid, 'time':{'$gte': +query.minTime, '$lt':+query.maxTime}};
        var cursor = db.collection('cash').find(condition).limit(500);
        cursor.each(function(err, item){
            if (cursor.isClosed()) {
                callback(); return;
            }
            resp.data.push([item.time, item.mod, item.act, item.num, item.remain, item.level, item.arg1, item.arg2]);
        });
    });
}

exports.action = function(query, resp, callback) {
    if (isNaN(query.minSid) || isNaN(query.maxSid) || isNaN(query.minTime) || isNaN(query.maxTime)) {
        resp.code = 1; resp.desc = 'invalid params'; 
        callback(); return;
    }


    var minSid = +query.minSid;
    var maxSid = +query.maxSid;
    var cashState = +query.cash | 0;

    var condition = {'time': {'$gte': +query.minTime, '$lte': +query.maxTime}};
    if (query.mod) {
        condition['mod'] = query.mod;
    }
    if (query.act) {
        condition['act'] = query.act;
    }
    if (cashState > 0) {
        condition['num'] = {'$gt': 0};
    } else if (cashState < 0) {
        condition['num'] = {'$lt': 0};
    }

    async.each(gServers.getSids(minSid, maxSid), function(sid, cb) {
        var db = gServers.getGameDB(sid);
        if (!db) {
            cb(); return;
        }

        var init = {'cash':0, 'times':0};
		var reduce = function(doc, prev) {
            prev.cash += doc.num;
            prev.times += 1;
        }

        var dbCash = db.collection('cash');
        dbCash.group({'mod':1, 'act':1}, condition, init, reduce, function(err, results){
            if (err || !results) {
                cb(util.format('server %d db error', sid)); return;
            }

            results.forEach(function(value){
                resp.data.push([sid, value.mod, value.act, value.cash, value.times]);
            });
            cb();
        });
    }, function(err) {
        if (err) {
            resp.code = 1; resp.desc = err;
        }
        callback();
    });
}

exports.actionDay = function(query, resp, callback) {
    if (isNaN(query.minSid) || isNaN(query.maxSid) || isNaN(query.minTime) || isNaN(query.maxTime)) {
        resp.code = 1; resp.desc = 'invalid params'; 
        callback(); return;
    }


    var minSid = +query.minSid;
    var maxSid = +query.maxSid;
    var cashState = +query.cash || 0;

    var condition = {'time': {'$gte': +query.minTime, '$lte': +query.maxTime}};
    if (query.mod) {
        condition['mod'] = query.mod;
    }
    if (query.act) {
        condition['act'] = query.act;
    }
    if (cashState > 0) {
        condition['num'] = {'$gt': 0};
    } else if (cashState < 0) {
        condition['num'] = {'$lt': 0};
    }

    async.each(gServers.getSids(minSid, maxSid), function(sid, cb) {
        var db = gServers.getGameDB(sid);
        if (!db) {
            cb(); return;
        }

		var keyf = function(doc){
            var time = new Date(doc.time*1000);
            time = Math.floor((+new Date(time.getFullYear(), time.getMonth(), time.getDate()))/1000);
            return {'time':time, 'mod':doc.mod, 'act':doc.act};
        }
        var init = {'cash':0, 'times':0};
		var reduce = function(doc, prev) {
            prev.cash += doc.num;
            prev.times += 1;
        }

        var dbCash = db.collection('cash');
        dbCash.group(keyf, condition, init, reduce, function(err, results){
            if (err || !results) {
                cb(util.format('server %d db error', sid)); return;
            }

            results.forEach(function(value){
                resp.data.push([sid, value.time, value.mod, value.act, value.cash, value.times]);
            });
            cb();
        });
    }, function(err) {
        if (err) {
            resp.code = 1; resp.desc = err;
        }
        callback();
    });
}

exports.inventoryDay = function(query, resp, callback) {
    if (isNaN(query.minSid) || isNaN(query.maxSid) || isNaN(query.minTime) || isNaN(query.maxTime)) {
        resp.code = 1; resp.desc = 'invalid params'; 
        callback(); return;
    }


    var minSid = +query.minSid;
    var maxSid = +query.maxSid;

    var condition = {'mod':'inventory', act:'buy', 'time': {'$gte': +query.minTime, '$lte': +query.maxTime}};
    if (query.id) {
        condition['arg1'] = +query.id;
    }

    async.each(gServers.getSids(minSid, maxSid), function(sid, cb) {
        var db = gServers.getGameDB(sid);
        if (!db) {
            cb(); return;
        }

		var keyf = function(doc){
            var time = new Date(doc.time*1000);
            time = Math.floor((+new Date(time.getFullYear(), time.getMonth(), time.getDate()))/1000);
            var id = doc.arg1 || 0;
            return {'time':time, 'id':id};
        }
        var init = {'cash':0, 'nums':0, 'times':0};
		var reduce = function(doc, prev) {
            prev.cash += doc.num;
            prev.nums += (doc.arg2||0);
            prev.times += 1;
        }

        var dbCash = db.collection('cash');
        dbCash.group(keyf, condition, init, reduce, function(err, results){
            if (err || !results) {
                cb(util.format('server %d db error', sid)); return;
            }

            results.forEach(function(value){
                resp.data.push([sid, value.time, value.id, value.nums, value.cash, value.times]);
            });
            cb();
        });
    }, function(err) {
        if (err) {
            resp.code = 1; resp.desc = err;
        }
        callback();
    });
}

exports.oldAction = function(query, resp, callback){
    if (isNaN(query.sid) || !query.hasOwnProperty('openid') ||
        !query.hasOwnProperty('minTime') || !query.hasOwnProperty('maxTime')) {
        resp.code = 1; resp.desc = 'invalid params';
        callback(); return;
    }

    var sid = +query.sid;
    var openid = query.openid;
    var minTime = +query.minTime;
    var maxTime = +query.maxTime;

    minTime = Date.createFromStamp(minTime).stdFormatedString();
    maxTime = Date.createFromStamp(maxTime).stdFormatedString();

    var db = gServers.getGameDB(sid);
    if (!db) {
        resp.code = 1; resp.desc = 'invalid server';
        callback(); return;
    }

    var _Sum = [];

    var uids = [];
    async.series([
        // 查询玩家UID列表
        function(cb) {
            db.collection('plat').find({_id:openid}).toArray(function(err, arr){
                if (!err && arr.length > 0) {
                    if (arr[0].uids) uids = arr[0].uids;
                    else uids.push(arr[0].uid);
                }
                cb(null);
            });
        },
        function(cb) {
            if (uids.length <= 0) {
                cb(null);
                return;
            }

            var cursor = db.collection('analysis').find({
                "uid":{
                    "$in": uids
                },
                "date":{
                    "$gte": minTime,
                    "$lt": maxTime
                }
            });

            cursor.each(function(err, item){
                if (cursor.isClosed()) {
                    cb(); return;
                }

                if (!err && item) {
                    _Sum.push([
                        item.uid,
                        item.action,
                        item.cash,
                        item.c1,
                        item.c2,
                        item.date
                    ]);
                }
            });
        }
    ], function(err){
        resp.data = _Sum;
        callback();
    });
};

exports.queryPay = function(query, resp, callback){
    if (isNaN(query.sid) || !query.hasOwnProperty('minTime')
        || !query.hasOwnProperty('maxTime') || !query.hasOwnProperty("queryNum")) {
        resp.code = 1; resp.desc = 'invalid params';
        callback(); return;
    }

    var sid = +query.sid;                   // 查询的服务器ID
    var queryNum = +query.queryNum;         // 查询多少条数据
    var minTime = +query.minTime;           // 查询起始时间
    var maxTime = +query.maxTime;           // 查询结束时间

    var db = gServers.getGameDB(sid);
    if (!db) {
        resp.code = 1; resp.desc = 'invalid server';
        callback(); return;
    }

    db.collection('pay').group({openid:1},
        {"ts":{
            "$gte":minTime + "",
            "$lt":maxTime + ""
            }
        },
        {sum:0},
        function(doc, prev) {
            prev.sum += +doc.amt;
        },
        function(err, res){
            if (err) {
                resp.code = 1; resp.desc = util.format("%j", err);
                callback();
            } else {
                var retArr = [];
                res.forEach(function(value){
                    retArr.push([
                        value.openid,
                        value.sum
                    ]);
                });
                retArr.sort(function(a, b){ return b[1] - a[1]; });
                retArr = retArr.splice(0, queryNum);

                resp.code = 0;
                resp.data = retArr;
                callback();
            }
        }
    );
};